package cn.elwy.osgi.config.util;

import java.io.File;
import java.net.URL;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;

import cn.elwy.common.exception.RunException;
import cn.elwy.common.log.Logger;
import cn.elwy.common.log.LoggerFactory;
import cn.elwy.common.util.PathSupport;

/**
 * 获取资源工具类
 * @author huangsq
 * @version 1.0
 * @Copyright 2015-2020 By www.elwy.cn All Right Reserved.
 */
public class RcpPathSupport extends PathSupport {

	private Logger logger = LoggerFactory.getLogger(RcpPathSupport.class);

	private static RcpPathSupport instance = new RcpPathSupport();
	/** 产品路径 */
	public File PRODUCT_PATH;
	/** 产品URL */
	public URL PRODUCT_URL;
	/** 工作空间路径 */
	public static File WORKSPACE_PATH;
	/** 工作空间URL */
	public static URL WORKSPACE_URL;
	/** 产品配置文件目录 */
	public static File CONFIGURATION_PATH;
	/** 产品日志文件 */
	public static File LOG_FILE;

	/**
	 * 获取资源工具类的构造函数
	 */
	private RcpPathSupport() {
	}

	public static RcpPathSupport getInstance() {
		return instance;
	}

	/** 获取安装目录 */
	public File getInstallHome() {
		if (installHome == null) {
			installHome = toFile(getInstallURL());
		}
		return installHome;
	}

	/** 获取安装路径 */
	public URL getInstallURL() {
		if (installUrl == null) {
			try {
				installUrl = toFileURL(Platform.getInstallLocation().getURL());
			} catch (Throwable e) {
				logger.error(e.getMessage(), e);
			}
		}
		return installUrl;
	}

	/** 获取安装目录 */
	public String getInstallPath() {
		if (installPath == null) {
			installPath = getFormatPath(getInstallHome());
		}
		return installPath;
	}

	/** 获取工作空间根目录 */
	public File getWorkspacePath() {
		if (WORKSPACE_PATH == null) {
			return toFile(getWorkspaceURL());
		}
		return WORKSPACE_PATH;
	}

	/** 获取工作空间根目录 */
	public URL getWorkspaceURL() {
		if (WORKSPACE_URL == null) {
			return Platform.getInstanceLocation().getURL();
		}
		return WORKSPACE_URL;
	}

	/** 获取产品根路径 */
	public File getProductPath() {
		if (PRODUCT_PATH == null) {
			return toFile(getProductURL());
		}
		return PRODUCT_PATH;
	}

	/** 获取产品根目录 */
	public URL getProductURL() {
		if (PRODUCT_URL == null) {
			return toFileURL(Platform.getProduct().getDefiningBundle().getEntry(""));
		}
		return PRODUCT_URL;
	}

	/** 获取产品配置根目录 */
	public File getConfigurationPath() {
		if (CONFIGURATION_PATH == null) {
			return toFile(Platform.getConfigurationLocation().getURL());
		}
		return CONFIGURATION_PATH;
	}

	/** 获取产品LOG路径 */
	public File getLogFile() {
		if (LOG_FILE == null) {
			return Platform.getLogFileLocation().toFile();
		}
		return LOG_FILE;
	}

	/** 获取组件绝对路径 */
	public File getStateLocation(Bundle bundle) {
		return Platform.getStateLocation(bundle).toFile();
	}

	/**
	 * 获取资源文件地址，先查找USER_DIR目录，再查APP_DIR目录最后查找clazz所在组件的目录，找到其中一个直接返回，如果不存在指定的资源将返回null
	 * @param filePath 相对路径
	 * @return
	 */
	public URL getResources(String filePath) {
		return getResources((Class<?>) null, filePath);
	}

	/**
	 * 获取资源文件地址，先查找USER_DIR目录，再查APP_DIR目录最后查找clazz所在组件的目录，找到其中一个直接返回，如果不存在指定的资源将返回null
	 * @param clazz 组件下的类
	 * @param filePath 相对路径
	 * @return
	 */
	public URL getResources(Class<?> clazz, String filePath) {
		URL url = getResource(configHomeUrl, filePath);
		if (url == null) {
			url = getResource(installUrl, filePath);
			if (url == null && !appHomePath.equalsIgnoreCase(configHomePath)) {
				url = getResource(appHomeUrl, filePath);
			}
		}
		if (url == null) {
			url = getBundleResource(clazz, filePath);
		}
		if (url == null) {
			url = toFileURL(getResource(clazz, filePath));
		}
		return url;
	}

	/**
	 * 获取资源文件地址，先查找USER_DIR目录，再查APP_DIR目录最后查找clazz所在组件的目录，找到其中一个直接返回，如果不存在指定的资源将返回null
	 * @param filePath 相对于组件的路径
	 * @return
	 */
	public File getResourcesFile(String filePath) {
		return getResourcesFile((Class<?>) null, filePath);
	}

	/**
	 * 获取资源文件地址，先查找USER_DIR目录，再查APP_DIR目录最后查找clazz所在组件的目录，找到其中一个直接返回，如果不存在指定的资源将返回null
	 * @param clazz 组件下的类
	 * @param filePath 相对于组件的路径
	 * @return
	 */
	public File getResourcesFile(Class<?> clazz, String filePath) {
		return toFile(getResources(clazz, filePath));
	}

	/**
	 * 获取相对于组件的URL资源，如果不存在指定的资源将返回null
	 * @param clazz 所在组件的类
	 * @param filePath 相对于组件的路径
	 * @return
	 */
	public URL getBundleResource(Class<?> clazz, String filePath) {
		if (clazz == null) {
			clazz = RcpPathSupport.class;
		}
		Bundle bundle = FrameworkUtil.getBundle(clazz);
		return getBundleResource(bundle, filePath);
	}

	/**
	 * 获取相对于组件的URL资源，如果不存在指定的资源将返回null
	 * @param bundleId 组件ID
	 * @param filePath 相对于组件的路径
	 * @return
	 */
	public URL getBundleResource(String bundleId, String filePath) {
		return getBundleResource(Platform.getBundle(bundleId), filePath);
	}

	/**
	 * 获取相对于组件的URL资源，如果不存在指定的资源将返回null
	 * @param bundle 组件Bundle
	 * @param filePath 相对于组件的路径
	 * @return
	 */
	public URL getBundleResource(Bundle bundle, String filePath) {
		return toFileURL(bundle.getEntry(getFilePath(filePath)));
	}

	/**
	 * 获取相对于组件的URL资源，如果不存在指定的资源将返回null
	 * @param bundleId 组件ID
	 * @param filePath
	 * @return
	 */
	public File getBundleResourceFile(String bundleId, String filePath) {
		return toFile(getBundleResource(bundleId, filePath));
	}

	/**
	 * 获取相对于组件的URL资源，如果不存在指定的资源将返回null
	 * @param clazz 所在组件的类
	 * @param filePath
	 * @return
	 */
	public File getBundleResourceFile(Class<?> clazz, String filePath) {
		return toFile(getBundleResource(clazz, filePath));
	}

	/**
	 * 获取相对于组件的URL资源，如果不存在指定的资源将返回null
	 * @param filePath
	 * @return
	 */
	public File getBundleResourceFile(Bundle bundle, String filePath) {
		return toFile(getBundleResource(bundle, filePath));
	}

	/**
	 * 组件的URL转换成File
	 * @param url 组件的URL
	 * @return
	 */
	public File toFile(URL url) {
		if (url == null) {
			return null;
		} else {
			Path path = new Path(url.getFile());
			return path.toFile();
		}
	}

	/**
	 * 组件的URL转换成URL
	 * @param url 组件的URL
	 * @return
	 */
	public URL toFileURL(URL url) {
		if (url == null) {
			return null;
		}
		try {
			return FileLocator.toFileURL(url);
		} catch (Exception e) {
			throw new RunException(e);
		}
	}

}